package com.web.managedbean;

import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.database.bean.Game;
import com.database.bean.News;
import com.database.bean.Round;
import com.database.bean.User;
import com.security.util.SecurityUtil;
import com.util.FormatUtil;

@Controller
@ManagedBean(name="userMBean")
@SessionScoped
@Scope("session")
public class UserMBean extends AbstractManagedBean {
	
	private static final long serialVersionUID = 1L;

	private User user;
	private String nickname= "";
	private boolean admin=false;
	private String roundInformation="";
	private String userName="";
	private String userMail="";
	private String userPassword="";
	private boolean setPassword=false;

	
	public UserMBean() {
		super();
	}

	
	public StreamedContent getUserManualFile() {
		InputStream stream = ((ServletContext)FacesContext.getCurrentInstance().getExternalContext().getContext()).getResourceAsStream("/resources/pdf/userManual.pdf");
	    DefaultStreamedContent file = new DefaultStreamedContent(stream, "application/pdf", "userManual.pdf");
        return file;
    }
	
	public StreamedContent getAdminManualFile() {
		InputStream stream = ((ServletContext)FacesContext.getCurrentInstance().getExternalContext().getContext()).getResourceAsStream("/resources/pdf/adminManual.pdf");
	    DefaultStreamedContent file = new DefaultStreamedContent(stream, "application/pdf", "adminManual.pdf");
        return file;
    }
	
	public String actionGotoUserMainPage(){
		if(user.isAdmin()){
			return "adminMain?faces-redirect=true";
		}
		else{
			return "companyMain?faces-redirect=true";
		}
	}
	
	public User getUser() {
		
		if(user == null) {
			FacesContext context = FacesContext.getCurrentInstance();
			HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();
			HttpSession httpSession = request.getSession(false);
			user = (User) httpSession.getAttribute("user");
			if(user != null){
				System.out.println("------- getUser");
				nickname = user.getNickname();
				admin=user.isAdmin();
				userName=this.user.getNickname();
				userMail=this.user.getEmail();
			}
		}
		
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}
	
	public String logout() {
		Map<String,Object> sessionMap=FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
		System.out.println(sessionMap.keySet());
		
		
		FacesContext context = FacesContext.getCurrentInstance();
		HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();
		HttpSession httpSession = request.getSession(false);
		httpSession.invalidate();
		
		FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
		
		this.user = null;
		return "index?faces-redirect=true";
	}
	
	
	public String getGreeting(){
		getUser();
		if(this.nickname!=null && this.nickname.length()>=1){
			return "Hello, "+this.nickname;
		}

		return "Hello";
	}

	public String getNickname() {
		return nickname;
	}

	public void setNickname(String nickname) {
		this.nickname = nickname;
	}


	public boolean isAdmin() {
		return admin;
	}


	public void setAdmin(boolean admin) {
		this.admin = admin;
	}


	/**
	 * @return the roundInformation
	 */
	public String getRoundInformation() {
		if(this.user!=null && !this.user.isAdmin()){
			Game game = this.user.getGame();
			if(game!=null){
				Round round = game.getConfigurableRound();
				if(round!=null){
					this.roundInformation = "Round-Nr: " + round.getRoundNumber() + ", Decisions til: " + FormatUtil.dateTimeFormatter.format(round.getEndDate());
				}else{
					this.roundInformation = "There is actually no configurable Round!";
				}
			}else{
				this.roundInformation = "There is actually no valid game for your company available!";
			}
		}
		
		return roundInformation;
	}
	
	public String actionUpdateUser() {
		try{
			this.user.setNickname(this.userName);
			this.user.setEmail(this.userMail);
			if(setPassword){
				byte[] bSalt=SecurityUtil.createSalt();
				String salt=SecurityUtil.encodeBase64(bSalt);
				this.user.setSalt(salt);
				byte[] bHash=SecurityUtil.getHash(this.userPassword, bSalt);			
				String password=SecurityUtil.encodeBase64(bHash);
				this.user.setPassword(password);
			}

			this.adminService.update(this.user);	
			
			this.userPassword="";
			
			if(user.isAdmin()){
				return "adminMain?faces-redirect=true";
			}
			else{
				return "companyMain?faces-redirect=true";
			}
		}
		catch (RuntimeException e){
			e.printStackTrace();
			this.addErrorMessage("Error at saving AgentType!");
			return "";
		} catch (NoSuchAlgorithmException e) {
			this.addErrorMessage("Error at saving AgentType!");
			e.printStackTrace();
			return "";
		} catch (UnsupportedEncodingException e) {
			this.addErrorMessage("Error at saving AgentType!");
			e.printStackTrace();
			return "";
		}
		finally{
			setPassword=false;
		}
    }
	

	public String getUserName() {
		return userName;
	}


	public void setUserName(String userName) {
		this.userName = userName;
	}


	public String getUserMail() {
		return userMail;
	}


	public void setUserMail(String userMail) {
		this.userMail = userMail;
	}


	public String getUserPassword() {
		return userPassword;
	}


	public void setUserPassword(String userPassword) {
		this.userPassword = userPassword;
	}

	public List<News> getTopGameNews(){
		if(this.user!=null && this.user.getGame()!=null){
			return adminService.getLastNewsForGame(this.user.getGame(), 10);
		}
		else{
			return new ArrayList<News>();
		}
	}
	
	public List<News> getGameNews(){
		if(this.user!=null && this.user.getGame()!=null){
			return adminService.getLastNewsForGame(this.user.getGame(), null);
		}
		else{
			return new ArrayList<News>();
		}
	}


	public boolean isSetPassword() {
		return setPassword;
	}


	public void setSetPassword(boolean setPassword) {
		this.setPassword = setPassword;
	}

	
	
}
